const axios = require('axios');

// 请求队列，每个元素包含一个请求的配置和回调函数
const requestQueue = [];

// 最大并发请求数量
const maxConcurrentRequests = 2;

// 当前正在进行的请求数量
let currentConcurrentRequests = 0;

// 创建一个Axios实例，可以设置一些全局的配置
const axiosInstance = axios.create({
    baseURL: 'https://api.example.com',
    timeout: 5000
});

// 添加请求拦截器
axiosInstance.interceptors.request.use(
    (config) => {
        // 在发送请求之前做些什么
        // 可以在请求头中添加token等信息
        return config;
    },
    (error) => {
        // 对请求错误做些什么
        return Promise.reject(error);
    }
);

// 添加响应拦截器
axiosInstance.interceptors.response.use(
    (response) => {
        // 对响应数据做些什么
        // 可以检查接口返回的状态码，并在某些情况下自动处理错误

        // 减少正在进行的请求数量
        currentConcurrentRequests--;

        // 如果还有未处理的请求，继续发送请求
        if (requestQueue.length > 0) {
            const nextRequest = requestQueue.shift();
            sendRequest(nextRequest.config, nextRequest.callback);
        }

        return response;
    },
    (error) => {
        // 对响应错误做些什么
        return Promise.reject(error);
    }
);

// 发送请求的函数
const sendRequest = (config, callback, retryCount = 0) => {
    // 如果当前正在进行的请求数量达到最大并发请求数量，等待一段时间再发送请求
    if (currentConcurrentRequests >= maxConcurrentRequests) {
        setTimeout(() => {
            sendRequest(config, callback, retryCount);
        }, 100);
        return;
    }

    // 增加正在进行的请求数量
    currentConcurrentRequests++;

    axiosInstance(config)
        .then((response) => {
            // 请求成功，执行回调函数
            callback(response);
        })
        .catch((error) => {
            // 请求失败，重试
            if (retryCount < 3) {
                console.log(`Request failed, retrying (${retryCount + 1})...`);
                sendRequest(config, callback, retryCount + 1);
            } else {
                console.log(`Request failed after ${retryCount} retries.`);
            }
        });
};

// 重写axiosInstance方法
const axiosInstanceWithQueue = (config) => {
    return new Promise((resolve, reject) => {
        requestQueue.push({
            config: config,
            callback: (response) => {
                resolve(response);
            }
        });
        if (requestQueue.length === 1 && currentConcurrentRequests < maxConcurrentRequests) {
            const nextRequest = requestQueue.shift();
            sendRequest(nextRequest.config, nextRequest.callback);
        }
    });
};

module.exports = axiosInstanceWithQueue;